﻿using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace GraphConfigTool
{
    public partial class ConfigHeaterStrip : Form
    {
        HeaterStripTransformer transformer;
        LineHeaterStrip lineHeaterStrip;
        CurvedHeaterStrip curvedHeaterStrip;
        HeaterStripRect heaterStripRect;
        LineHeaterStrip copyLineHeaterStrip;
        CurvedHeaterStrip copyCurvedHeaterStrip;

        //数据的存储和保存
        public List<HeaterStripTransformer> transformerList = new List<HeaterStripTransformer>();//插入文本框的集合
        public List<LineHeaterStrip> lineHeaterStripList = new List<LineHeaterStrip>();//插入线段的集合
        public List<CurvedHeaterStrip> curvedHeaterStripList = new List<CurvedHeaterStrip>();//插入隔离变集合
        public List<HeaterStripRect> heaterStripRectList = new List<HeaterStripRect>();//插入方框
        public int my_border = 5;//边缘宽度 判断改变鼠标形态的跨度

        Rectangle old_rect;
        Point old_line_point1;
        Point old_line_point2;
        Point old_transformer_point1;
        Point old_transformer_point2;
        Point old_transformer_point3;
        Point old_transformer_point4;
        //CurvedHeaterStrip old_curvedHeaterStrip;//这种形式为什么不行？？？？？
        public ResizeType m_type;
        public Point dragPoint = new Point();//拖拽起始坐标点
        public int insertIndex = 0;//记录插入的索引
        public bool isMouseDown = false;//鼠标落下标志 按住鼠标 再进行鼠标形态改变和移动
        public bool onResize = false;//是否改变边界条件
        public bool isOpenResize = false;//是否打开改变边界功能 默认 否
        bool insertTransformerFlag = false;//是否为插入变压器模式
        bool insertLineFlag = false;
        bool insertCurvedHeaterStripFlag = false;
        bool insertRectFlag = false;
        public bool inRectFlag = false;//鼠标是否在矩形内
        public bool isBorderFlag = false;//框的边界
        public bool isMoveFlag = false;//是否开始移动
        public bool isMoveLineFlag = false;//是否在移动线段
        public bool isMoveTransformerFlag = false;
        public int changeTransformerIndex = -1;//-1代表没有选中方框
        public int changeLineIndex = -1;
        public int changeCurvedIndex = -1;
        public int changeRectIndex = -1;
        public TextBox nameTextBox;//矩形框内部文字模块
        public ComboBox transformerNameBox1;
        public ComboBox transformerNameBox2;
        public TextBox box;
        public Size nameSize;
        public int changeTransformNameIndex = -1;//名称索引 唯一
        public int changeLineNameIndex = -1;
        public int changeCurvedNameIndex = -1;
        bool isCopy = false;

        public enum ResizeType
        {
            Left,
            Right,
            Top,
            Bottom,
            LeftTop,
            RightTop,
            LeftBottom,
            RightBottom,
        }

        public enum GraphType
        {
            type_default,//默认
            type_rect,//虚线框
            type_transformer,//变压器
            type_line,//直线型
            type_curved,//弯曲型

        };

        public ConfigHeaterStrip()
        {
            InitializeComponent();
            DoubleBuffered = true;
        }
        //加入ID索引 准确找到当前道岔
        public ConfigHeaterStrip(string text, List<HeaterStripTransformer> transformers, List<LineHeaterStrip> lineHeaterStrips,
            List<CurvedHeaterStrip> curvedHeaterStrips, List<HeaterStripRect> heaterStripRects)
        {
            InitializeComponent();
            DoubleBuffered = true;
            this.Text = text + this.Text;
            transformerList = transformers;
            lineHeaterStripList = lineHeaterStrips;
            curvedHeaterStripList = curvedHeaterStrips;
            heaterStripRectList = heaterStripRects;
        }
        public ConfigHeaterStrip(string text)
        {
            InitializeComponent();
            DoubleBuffered = true;
            this.Text = text + this.Text;
        }

        private void ConfigHeaterStrip_Paint(object sender, PaintEventArgs e)
        {
            foreach (HeaterStripTransformer heater in transformerList)
            {
                e.Graphics.DrawRectangle(heater.pen, heater.rect);
                e.Graphics.FillRectangle(new SolidBrush(Color.DarkSlateGray), heater.rect);
                nameSize = TextRenderer.MeasureText(heater.name, heater.font);
                heater.nameLocation = new Point(heater.rect.X + heater.rect.Width / 2 - nameSize.Width / 2, heater.rect.Y + heater.rect.Height / 2 - nameSize.Height / 2);
                e.Graphics.DrawString(heater.name, heater.font, new SolidBrush(Color.FromArgb(255, 255, 255)), heater.nameLocation);
            }

            foreach (LineHeaterStrip line in lineHeaterStripList)
            {
                //画水平线 鼠标点击位置 长度为在类中设置的长度
                e.Graphics.DrawLine(new Pen(line.penColor, line.lineWidth), line.point1, line.point2);
                nameSize = TextRenderer.MeasureText(line.value + line.unit, line.font);
                if (line.isVertical)
                {
                    line.nameLocation = new Point((line.point1.X + line.point2.X) / 2 - nameSize.Width / 2 + 20, (line.point1.Y + line.point2.Y) / 2 - nameSize.Height / 2);
                }
                else
                {
                    line.nameLocation = new Point((line.point1.X + line.point2.X) / 2 - nameSize.Width / 2, (line.point1.Y + line.point2.Y) / 2 - nameSize.Height / 2 - 10);
                }
                e.Graphics.DrawString(line.value + line.unit, line.font, new SolidBrush(line.nameColor), line.nameLocation);
            }

            foreach (CurvedHeaterStrip curved in curvedHeaterStripList)
            {
                //先画线 这样文字就会在上面 有层级关系
                e.Graphics.DrawLines(new Pen(curved.penColor, curved.lineWidth), curved.points);
                nameSize = TextRenderer.MeasureText(curved.value + curved.unit, curved.font);
                curved.nameLocation = new Point((curved.point1.X + curved.point3.X) / 2 - nameSize.Width / 2, (curved.point2.Y + curved.point4.Y) / 2 - nameSize.Height / 2);
                e.Graphics.DrawString(curved.value + curved.unit, curved.font, new SolidBrush(curved.nameColor), curved.nameLocation);
            }

            foreach (HeaterStripRect rect in heaterStripRectList)
            {
                e.Graphics.DrawRectangle(rect.pen, rect.rect);
            }
        }

        private void ConfigHeaterStrip_MouseMove(object sender, MouseEventArgs e)
        {
            //Console.WriteLine(PointToClient(MousePosition));
            //Console.WriteLine(e.Location);
            //在线段没选中的情况下进行移动 一旦选中 则只判断移动其中的一个
            if (changeLineIndex == -1 && changeCurvedIndex == -1 && changeTransformerIndex == -1)
            {
                MouseMoveRect(e);
            }
            if (changeLineIndex == -1 && changeCurvedIndex == -1 && changeRectIndex == -1)
            {
                mouseMoveTransformer(e);
            }
            if (changeTransformerIndex == -1 && changeCurvedIndex == -1 && changeRectIndex == -1)
            {
                MouseMoveLine(e.Location);
            }
            if (changeLineIndex == -1 && changeTransformerIndex == -1 && changeRectIndex == -1)
            {
                MouseMoveCurved(e.Location);
            }

        }

        public void MouseMoveRect(MouseEventArgs e)
        {
            if (isMouseDown && changeRectIndex != -1)
            {
                HeaterStripRect heaterStripRect = heaterStripRectList[changeRectIndex];
                Rectangle rect = heaterStripRect.rect;
                if (onResize)
                {
                    //将选中的矩形框单独拿出来进行操作 在循环中操作 容易在过程中出问题
                    heaterStripRectList[changeRectIndex].rect = ChangeShape(e, ref rect);
                    return;
                }
                else if (isMoveFlag)
                {
                    heaterStripRectList[changeRectIndex].rect = MoveRectangle(e, ref rect);
                    return;
                }
            }
            for (int i = 0; i < heaterStripRectList.Count; i++)
            {
                if (IsBorder(heaterStripRectList[i].rect, ref m_type))
                {
                    //在拖动时 限制住边界条件判断 则鼠标拖动不会改变鼠标形态
                    //赋值索引 找出该边界的矩形 
                    changeRectIndex = i;
                    isBorderFlag = true;//方便在鼠标落下事件绑定Resize条件
                    return;
                }
                isBorderFlag = false;
                //如果鼠标点击状态下 鼠标在长方形内部 则进行移动 并改变鼠标状态
                if (IsInRect(heaterStripRectList[i].rect, e))
                {
                    //记录索引
                    changeRectIndex = i;
                    inRectFlag = true;
                    return;
                }
                inRectFlag = false;
                changeRectIndex = -1;//不在边界和内部 索引赋值-1
            }
        }

        public void MouseMoveCurved(Point mouse_pt)
        {
            if (isMoveTransformerFlag && isMouseDown && changeCurvedIndex != -1)
            {
                MoveCurvedHeaterStrip(mouse_pt);
                return;
            }
            for (int i = 0; i < curvedHeaterStripList.Count; i++)
            {
                CurvedHeaterStrip transformer = curvedHeaterStripList[i];
                PointF closest;
                if (FindDistanceToSegmentSquared(mouse_pt, transformer.point1, transformer.point2, out closest) < 25 ||
                    FindDistanceToSegmentSquared(mouse_pt, transformer.point2, transformer.point3, out closest) < 25 ||
                    FindDistanceToSegmentSquared(mouse_pt, transformer.point3, transformer.point4, out closest) < 25)
                {
                    changeCurvedIndex = i;
                    Cursor = Cursors.SizeAll;
                    return;
                }
                else
                {
                    changeCurvedIndex = -1;
                    Cursor = Cursors.Default;
                }
            }
        }

        public void MoveCurvedHeaterStrip(Point mouse_pt)
        {
            curvedHeaterStrip = curvedHeaterStripList[changeCurvedIndex];
            int dx = mouse_pt.X - dragPoint.X;
            int dy = mouse_pt.Y - dragPoint.Y;
            curvedHeaterStrip.point1 = new Point(old_transformer_point1.X + dx, old_transformer_point1.Y + dy);
            curvedHeaterStrip.point2 = new Point(old_transformer_point2.X + dx, old_transformer_point2.Y + dy);
            curvedHeaterStrip.point3 = new Point(old_transformer_point3.X + dx, old_transformer_point3.Y + dy);
            curvedHeaterStrip.point4 = new Point(old_transformer_point4.X + dx, old_transformer_point4.Y + dy);
            curvedHeaterStrip.addPoints();
            Invalidate();
        }

        public void MouseMoveLine(Point mouse_pt)
        {
            if (isMoveLineFlag && isMouseDown && changeLineIndex != -1)
            {
                MoveLine(mouse_pt);
                return;
            }

            for (int i = 0; i < lineHeaterStripList.Count; i++)
            {
                LineHeaterStrip line = lineHeaterStripList[i];
                PointF closest;
                if (FindDistanceToSegmentSquared(mouse_pt, line.point1, line.point2, out closest) < 25)
                {
                    changeLineIndex = i;//记录索引值
                    Cursor = Cursors.SizeAll;
                    return;
                }
                else
                {
                    changeLineIndex = -1;
                    Cursor = Cursors.Default;
                }
            }
        }

        //移动线段
        public void MoveLine(Point mouse_pt)
        {
            lineHeaterStrip = lineHeaterStripList[changeLineIndex];
            int dx = mouse_pt.X - dragPoint.X;
            int dy = mouse_pt.Y - dragPoint.Y;
            lineHeaterStrip.point1 = new Point(old_line_point1.X + dx, old_line_point1.Y + dy);
            lineHeaterStrip.point2 = new Point(old_line_point2.X + dx, old_line_point2.Y + dy);
            Invalidate();
        }

        public void mouseMoveTransformer(MouseEventArgs e)
        {
            if (isMouseDown && changeTransformerIndex != -1)
            {
                HeaterStripTransformer heater = transformerList[changeTransformerIndex];
                Rectangle rect = heater.rect;
                if (onResize)
                {
                    //将选中的矩形框单独拿出来进行操作 在循环中操作 容易在过程中出问题
                    transformerList[changeTransformerIndex].rect = ChangeShape(e, ref rect);
                    return;
                }
                else if (isMoveFlag)
                {
                    transformerList[changeTransformerIndex].rect = MoveRectangle(e, ref rect);
                    return;
                }

            }
            for (int i = 0; i < transformerList.Count; i++)
            {
                if (isOpenResize && IsBorder(transformerList[i].rect, ref m_type))
                {
                    //在拖动时 限制住边界条件判断 则鼠标拖动不会改变鼠标形态
                    //赋值索引 找出该边界的矩形 
                    changeTransformerIndex = i;
                    isBorderFlag = true;//方便在鼠标落下事件绑定Resize条件
                    return;
                }
                isBorderFlag = false;
                //如果鼠标点击状态下 鼠标在长方形内部 则进行移动 并改变鼠标状态
                if (IsInRect(transformerList[i].rect, e))
                {
                    //记录索引
                    changeTransformerIndex = i;
                    inRectFlag = true;
                    return;
                }
                inRectFlag = false;
                changeTransformerIndex = -1;//不在边界和内部 索引赋值-1
            }
        }

        //计算鼠标到线段的距离
        private double FindDistanceToSegmentSquared(Point pt, Point p1, Point p2, out PointF closest)
        {
            float dx = p2.X - p1.X;
            float dy = p2.Y - p1.Y;
            if ((dx == 0) && (dy == 0))
            {
                // 鼠标是在端点上（线段就是一个点）
                closest = p1;
                dx = pt.X - p1.X;
                dy = pt.Y - p1.Y;
                return dx * dx + dy * dy;
            }

            // 距离值.
            float t = ((pt.X - p1.X) * dx + (pt.Y - p1.Y) * dy) / (dx * dx + dy * dy);

            if (t < 0)
            {
                closest = new PointF(p1.X, p1.Y);
                dx = pt.X - p1.X;
                dy = pt.Y - p1.Y;
            }
            else if (t > 1)
            {
                closest = new PointF(p2.X, p2.Y);
                dx = pt.X - p2.X;
                dy = pt.Y - p2.Y;
            }
            else
            {
                closest = new PointF(p1.X + t * dx, p1.Y + t * dy);
                dx = pt.X - closest.X;
                dy = pt.Y - closest.Y;
            }

            return dx * dx + dy * dy;
        }

        public bool IsBorder(Rectangle rect, ref ResizeType type)
        {
            Point cursorPoint = PointToClient(Cursor.Position);
            if (Math.Abs(cursorPoint.X - rect.Left) < my_border && Math.Abs(cursorPoint.Y - rect.Top) < my_border)
            {
                type = ResizeType.LeftTop;
                Cursor = Cursors.SizeNWSE;
            }
            else if (Math.Abs(cursorPoint.X - rect.Right) < my_border && Math.Abs(cursorPoint.Y - rect.Top) < my_border)
            {
                type = ResizeType.RightTop;
                Cursor = Cursors.SizeNESW;
            }
            else if (Math.Abs(cursorPoint.X - rect.Left) < my_border && Math.Abs(cursorPoint.Y - rect.Bottom) < my_border)
            {
                type = ResizeType.LeftBottom;
                Cursor = Cursors.SizeNESW;
            }
            else if (Math.Abs(cursorPoint.X - rect.Right) < my_border && Math.Abs(cursorPoint.Y - rect.Bottom) < my_border)
            {
                type = ResizeType.RightBottom;
                Cursor = Cursors.SizeNWSE;
            }
            else if (Math.Abs(cursorPoint.X - rect.Left) < my_border && cursorPoint.Y > rect.Top && cursorPoint.Y < rect.Bottom)
            {
                type = ResizeType.Left;
                Cursor = Cursors.SizeWE;
            }
            else if (Math.Abs(cursorPoint.X - rect.Right) < my_border && cursorPoint.Y > rect.Top && cursorPoint.Y < rect.Bottom)
            {
                type = ResizeType.Right;
                Cursor = Cursors.SizeWE;
            }
            else if (Math.Abs(cursorPoint.Y - rect.Bottom) < my_border && cursorPoint.X > rect.Left && cursorPoint.X < rect.Right)
            {
                type = ResizeType.Bottom;
                Cursor = Cursors.SizeNS;
            }
            else if (Math.Abs(cursorPoint.Y - rect.Top) < my_border && cursorPoint.X > rect.Left && cursorPoint.X < rect.Right)
            {
                type = ResizeType.Top;
                Cursor = Cursors.SizeNS;
            }
            else
            {
                Cursor = Cursors.Default;
                return false;
            }
            return true;

        }

        //改变形状
        public Rectangle ChangeShape(MouseEventArgs e, ref Rectangle rect)
        {
            int diffY = dragPoint.Y - e.Location.Y;
            int diffX = dragPoint.X - e.Location.X;
            switch (m_type)
            {
                //加入条件 可以四面八方随意拖动
                case ResizeType.Left:
                    if (old_rect.Right > e.Location.X)
                    {
                        rect = new Rectangle(old_rect.Left - diffX, old_rect.Top, old_rect.Width + diffX, old_rect.Height);
                    }
                    else
                    {
                        rect = new Rectangle(old_rect.Right, old_rect.Top, Math.Abs(old_rect.Width + diffX), old_rect.Height);
                    }
                    break;
                case ResizeType.Right:
                    if (old_rect.Left < e.Location.X)
                    {
                        rect = new Rectangle(old_rect.Left, old_rect.Top, old_rect.Width - diffX, old_rect.Height);
                    }
                    else
                    {
                        rect = new Rectangle(e.Location.X, old_rect.Top, Math.Abs(old_rect.Width - diffX), old_rect.Height);
                    }
                    break;
                case ResizeType.Top:
                    if (old_rect.Bottom > e.Location.Y)
                    {
                        rect = new Rectangle(old_rect.Left, old_rect.Top - diffY, old_rect.Width, old_rect.Height + diffY);
                    }
                    else
                    {
                        rect = new Rectangle(old_rect.Left, old_rect.Bottom, old_rect.Width, Math.Abs(old_rect.Height + diffY));
                    }
                    break;
                case ResizeType.Bottom:
                    if (old_rect.Top < e.Location.Y)
                    {
                        rect = new Rectangle(old_rect.Left, old_rect.Top, old_rect.Width, old_rect.Height - diffY);
                    }
                    else
                    {
                        rect = new Rectangle(old_rect.Left, e.Location.Y, old_rect.Width, Math.Abs(old_rect.Height - diffY));
                    }
                    break;
                case ResizeType.RightTop:
                    if (old_rect.Left < e.Location.X && old_rect.Bottom > e.Location.Y)
                    {
                        rect = new Rectangle(old_rect.Left, old_rect.Top - diffY, old_rect.Width - diffX, old_rect.Height + diffY);
                    }
                    else
                    {
                        rect = new Rectangle(Math.Min(old_rect.Left, e.Location.X), Math.Min(old_rect.Top - diffY, old_rect.Bottom), Math.Abs(old_rect.Width - diffX), Math.Abs(old_rect.Height + diffY));

                    }
                    break;
                case ResizeType.LeftTop:
                    if (old_rect.Right > e.Location.X && old_rect.Bottom > e.Location.Y)
                    {
                        rect = new Rectangle(old_rect.Left - diffX, old_rect.Top - diffY, old_rect.Width + diffX, old_rect.Height + diffY);
                    }
                    else
                    {
                        rect = new Rectangle(Math.Min(old_rect.Left - diffX, old_rect.Right), Math.Min(old_rect.Top - diffY, old_rect.Bottom), Math.Abs(old_rect.Width + diffX), Math.Abs(old_rect.Height + diffY));
                    }
                    break;
                case ResizeType.LeftBottom:
                    if (old_rect.Top < e.Location.Y && old_rect.Right > e.Location.X)
                    {
                        rect = new Rectangle(old_rect.Left - diffX, old_rect.Top, old_rect.Width + diffX, old_rect.Height - diffY);
                    }
                    else
                    {
                        rect = new Rectangle(Math.Min(old_rect.Left - diffX, old_rect.Right), Math.Min(old_rect.Top, e.Location.Y), Math.Abs(old_rect.Width + diffX), Math.Abs(old_rect.Height - diffY));
                    }
                    break;
                case ResizeType.RightBottom:
                    if (old_rect.Left < e.Location.X && old_rect.Top < e.Location.Y)
                    {
                        rect = new Rectangle(old_rect.Left, old_rect.Top, old_rect.Width - diffX, old_rect.Height - diffY);
                    }
                    else
                    {
                        rect = new Rectangle(Math.Min(old_rect.Left, e.Location.X), Math.Min(old_rect.Top, e.Location.Y), Math.Abs(old_rect.Width - diffX), Math.Abs(old_rect.Height - diffY));
                    }
                    break;
                default:
                    break;
            }
            Invalidate();
            return rect;
        }
        //坐标点是否在某个矩形内部
        public bool IsInRect(Rectangle rect, MouseEventArgs e)
        {
            //包含在矩形内部 除去边界的范围内
            if (rect.Top + my_border < e.Location.Y &&
                rect.Bottom - my_border > e.Location.Y &&
                rect.Left + my_border < e.Location.X &&
                rect.Right - my_border > e.Location.X)//鼠标按下后 再改变形态
            {
                if (isMouseDown)
                {
                    Cursor = Cursors.SizeAll;
                }
                else
                {
                    Cursor = Cursors.Default;
                }
                return true;
            }
            Cursor = Cursors.Default;
            return false;
        }

        public Rectangle MoveRectangle(MouseEventArgs e, ref Rectangle rect)
        {
            //移动相对位置 需要旧矩形的坐标 否则移动时会一直刷新
            Point newPoint = new Point(old_rect.X + e.Location.X - dragPoint.X, old_rect.Y + e.Location.Y - dragPoint.Y);
            Invalidate();
            return new Rectangle(newPoint, rect.Size);
        }

        private void ConfigHeaterStrip_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                if (insertTransformerFlag)
                {
                    insertIndex += 1;
                    transformer = new HeaterStripTransformer();
                    transformer.type = (int)GraphType.type_transformer;
                    transformer.index = insertIndex;
                    transformer.rect = new Rectangle(e.Location, transformer.initSize);
                    transformerList.Add(transformer);//将对象加入集合中

                    Invalidate();
                }
                else if (insertLineFlag)
                {
                    lineHeaterStrip = new LineHeaterStrip();
                    lineHeaterStrip.type = (int)GraphType.type_line;
                    lineHeaterStrip.point1 = e.Location;
                    lineHeaterStrip.point2 = lineHeaterStrip.calculatePoint(lineHeaterStrip.point1);
                    lineHeaterStripList.Add(lineHeaterStrip);//将线段对象加入集合中    
                    Invalidate();
                }
                else if (insertCurvedHeaterStripFlag)
                {
                    curvedHeaterStrip = new CurvedHeaterStrip();
                    curvedHeaterStrip.type = (int)GraphType.type_curved;
                    //curvedHeaterStrip.OnMyValueChanged += ListenValue_OnMyValueChanged;
                    curvedHeaterStrip.calculatePoint(e.Location);
                    curvedHeaterStrip.addPoints();
                    curvedHeaterStripList.Add(curvedHeaterStrip);
                    Invalidate();
                }
                else if (insertRectFlag)
                {
                    heaterStripRect = new HeaterStripRect(e.Location);
                    heaterStripRect.type = (int)GraphType.type_rect;
                    heaterStripRectList.Add(heaterStripRect);
                    Invalidate();
                }
                else
                {
                    isMouseDown = true;
                    //dragPoint = e.Location;//涉及到矩形的移动和改变大小的初值设定
                    if (changeTransformerIndex != -1)
                    {
                        //矩形框
                        dragPoint = e.Location;
                        old_rect = transformerList[changeTransformerIndex].rect;
                        //如果鼠标按下时 是边界 则触发大小调整条件
                        if (isBorderFlag && isOpenResize)
                        {
                            onResize = true;//在边界按下鼠标 Resize the Rectangle
                        }
                        else if (inRectFlag)//为了不使上下俩条件都满足 用 else if
                        {
                            IsInRect(transformerList[changeTransformerIndex].rect, e);
                            isMoveFlag = true;
                        }
                    }
                    if (changeRectIndex != -1)
                    {
                        //矩形框
                        dragPoint = e.Location;
                        old_rect = heaterStripRectList[changeRectIndex].rect;
                        //如果鼠标按下时 是边界 则触发大小调整条件
                        if (isBorderFlag)
                        {
                            onResize = true;//在边界按下鼠标 Resize the Rectangle
                        }
                        else if (inRectFlag)//为了不使上下俩条件都满足 用 else if
                        {
                            IsInRect(heaterStripRectList[changeRectIndex].rect, e);
                            isMoveFlag = true;
                        }
                    }

                    if (changeLineIndex != -1)
                    {
                        //线段
                        dragPoint = e.Location;
                        //准备移动线段 记录原始线段一边端点  从而可以算出偏移量
                        old_line_point1 = lineHeaterStripList[changeLineIndex].point1;
                        old_line_point2 = lineHeaterStripList[changeLineIndex].point2;
                        isMoveLineFlag = true;
                    }
                    if (changeCurvedIndex != -1)
                    {
                        dragPoint = e.Location;
                        old_transformer_point1 = curvedHeaterStripList[changeCurvedIndex].point1;
                        old_transformer_point2 = curvedHeaterStripList[changeCurvedIndex].point2;
                        old_transformer_point3 = curvedHeaterStripList[changeCurvedIndex].point3;
                        old_transformer_point4 = curvedHeaterStripList[changeCurvedIndex].point4;
                        //old_transformer = DeepCopyByReflect(transformerList[changeTransformerIndex]);
                        isMoveTransformerFlag = true;
                    }
                }
            }
            if (e.Button == MouseButtons.Right)
            {
                ContextMenuStripFunction(e);
            }
        }
        //鼠标右键菜单
        private void ContextMenuStripFunction(MouseEventArgs e)
        {
            //右键菜单
            if (changeLineIndex != -1 || changeCurvedIndex != -1 || changeRectIndex != -1)
            {
                //这三个 有一个选中时
                if (changeLineIndex != -1 || changeCurvedIndex != -1)
                {
                    configAddress.Visible = true;
                }
                else
                {
                    configAddress.Visible = false;
                }
                if (changeLineIndex != -1)
                {
                    lineHeaterStrip = lineHeaterStripList[changeLineIndex];
                    if (lineHeaterStrip.configAddressFlag)
                    {
                        configAddress.Text = "查看配置";
                    }
                    else
                    {
                        configAddress.Text = "配置地址";
                    }
                }
                if (changeCurvedIndex != -1)
                {
                    curvedHeaterStrip = curvedHeaterStripList[changeCurvedIndex];
                    if (curvedHeaterStrip.configAddressFlag)
                    {
                        configAddress.Text = "查看配置";
                    }
                    else
                    {
                        configAddress.Text = "配置地址";
                    }
                }
                //选中之后 展示的部分
                EditValue.Visible = true;
                delete.Visible = true;
                contextMenuStrip1.Show(this, e.Location);
                copy.Enabled = true;
                spin.Enabled = true;
                if (isCopy)
                {
                    paste.Enabled = true;
                }
                else
                {
                    paste.Enabled = false;
                }
            }
            else if (changeTransformerIndex != -1)
            {
                EditValue.Visible = true;
                delete.Visible = true;
                contextMenuStrip1.Show(this, e.Location);
                if (isCopy)
                {
                    paste.Enabled = true;
                }
                else
                {
                    paste.Enabled = false;
                }
                copy.Enabled = false;
                spin.Enabled = false;
                configAddress.Visible = false;
            }
            else
            {
                //在空白处 点击右键后展示
                EditValue.Visible = false;
                delete.Visible = false;
                contextMenuStrip1.Show(this, e.Location);
                copy.Enabled = false;
                spin.Enabled = false;
                configAddress.Visible = false;
                if (isCopy)
                {
                    paste.Enabled = true;
                }
                else
                {
                    paste.Enabled = false;
                }
            }
        }

        private void ListenValue_OnMyValueChanged(object sender, EventArgs e)
        {
            Invalidate();
        }

        private void ConfigHeaterStrip_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                //释放资源 标签还原
                isMouseDown = false;
                insertTransformerFlag = false;
                insertLineFlag = false;
                insertCurvedHeaterStripFlag = false;
                insertRectFlag = false;
                onResize = false;
                isMoveFlag = false;
                isMoveLineFlag = false;
                isMoveTransformerFlag = false;
                dragPoint = Point.Empty;
                old_rect = new Rectangle();
                old_line_point1 = Point.Empty;
                old_line_point2 = Point.Empty;
                old_transformer_point1 = Point.Empty;
                old_transformer_point2 = Point.Empty;
                old_transformer_point3 = Point.Empty;
                old_transformer_point4 = Point.Empty;
                //old_transformer = null;
                changeTransformerIndex = -1;//索引初始化
                changeLineIndex = -1;
                changeCurvedIndex = -1;
            }
        }

        private void ConfigHeaterStrip_DoubleClick(object sender, EventArgs e)
        {
            //在方框外部双击 赋值给新的方框
            if (transformerNameBox1 != null || transformerNameBox2 != null)
            {
                if (transformerNameBox1 == null || transformerNameBox2 == null)
                {
                    MessageBox.Show("请输入变压器容量");
                    return;
                }
                transformerList[changeTransformNameIndex].name = transformerNameBox1.Text + "/" + transformerNameBox2.Text;
                this.Controls.Remove(transformerNameBox1);
                this.Controls.Remove(transformerNameBox2);
                transformerNameBox1 = null;
                transformerNameBox2 = null;
                changeTransformNameIndex = -1;
                Invalidate();
            }
            if (box != null)
            {
                if (changeLineNameIndex != -1)
                {
                    //TODO 数值 如果输入字母怎么办？ 还未处理~
                    lineHeaterStripList[changeLineNameIndex].Value = int.Parse(box.Text);
                    changeLineNameIndex = -1;
                    this.Controls.Remove(box);
                    box = null;
                    Invalidate();
                }
            }
        }

        private void OpenResize_Click(object sender, EventArgs e)
        {
            openResize.Enabled = false;
            openResize.Checked = true;
            closeResize.Enabled = true;
            closeResize.Checked = false;
            isOpenResize = true;
        }

        private void CloseResize_Click(object sender, EventArgs e)
        {
            closeResize.Enabled = false;
            closeResize.Checked = true;
            openResize.Enabled = true;
            openResize.Checked = false;
            isOpenResize = false;
        }

        private void ClearScreen_Click(object sender, EventArgs e)
        {
            DialogResult result = MessageBox.Show("确定清屏吗", "清屏", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2);
            if (result == DialogResult.OK)
            {
                transformerList.Clear();
                lineHeaterStripList.Clear();
                curvedHeaterStripList.Clear();
                Invalidate();
            }
        }

        private void Spin_Click(object sender, EventArgs e)
        {
            if (changeLineIndex != -1)
            {
                //如果对线段进行了选择 则顺时针旋转90度
                //公式： 顺时针 x' = (x - x0)cosα + (y - y0)sinα + x0;
                //             y' = (y - y0)cosα - (x - x0)sinα + y0;
                //逆时针 将α变为-α即可 cos-α = cosα; sin-α = -sinα
                lineHeaterStrip = lineHeaterStripList[changeLineIndex];
                Point point1 = lineHeaterStrip.point1;
                Point point2 = lineHeaterStrip.point2;
                Point center = new Point((point1.X + point2.X) / 2, (point1.Y + point2.Y) / 2);
                //逆时针旋转90度 cos90 = 0 sin90 = 1       
                lineHeaterStrip.point1 = new Point(point1.Y - center.Y + center.X, center.Y - point1.X + center.X);
                lineHeaterStrip.point2 = new Point(point2.Y - center.Y + center.X, center.Y - point2.X + center.X);
                lineHeaterStrip.isVertical = !lineHeaterStrip.isVertical;
                Invalidate();
            }
            else if (changeCurvedIndex != -1)
            {
                curvedHeaterStrip = curvedHeaterStripList[changeCurvedIndex];
                Point point1 = curvedHeaterStrip.point1;
                Point point2 = curvedHeaterStrip.point2;
                Point point3 = curvedHeaterStrip.point3;
                Point point4 = curvedHeaterStrip.point4;
                Point center = new Point((point2.X + point3.X) / 2, (point2.Y + point3.Y) / 2);
                //顺时针旋转
                curvedHeaterStrip.point1 = new Point(center.Y - point1.Y + center.X, point1.X - center.X + center.Y);
                curvedHeaterStrip.point2 = new Point(center.Y - point2.Y + center.X, point2.X - center.X + center.Y);
                curvedHeaterStrip.point3 = new Point(center.Y - point3.Y + center.X, point3.X - center.X + center.Y);
                curvedHeaterStrip.point4 = new Point(center.Y - point4.Y + center.X, point4.X - center.X + center.Y);
                curvedHeaterStrip.addPoints();
                Invalidate();
            }

        }

        private void Copy_Click(object sender, EventArgs e)
        {
            if (changeLineIndex != -1)
            {
                //得到选中的线段
                lineHeaterStrip = lineHeaterStripList[changeLineIndex];
                //进行深拷贝
                copyLineHeaterStrip = DeepCopyByReflect(lineHeaterStrip);
                isCopy = true;
            }
            else if (changeCurvedIndex != -1)
            {
                curvedHeaterStrip = curvedHeaterStripList[changeCurvedIndex];
                copyCurvedHeaterStrip = DeepCopyByReflect(curvedHeaterStrip);
                isCopy = true;
            }
        }


        //深拷贝 反射
        public static T DeepCopyByReflect<T>(T obj)
        {
            //如果是字符串或值类型则直接返回
            if (obj == null || (obj is string) || (obj.GetType().IsValueType)) return obj;
            //反射创建对象时，有参数的会看原来的对象里是否有相应参数的构造函数
            object retval = Activator.CreateInstance(obj.GetType(), new object[] { new Color(), 0 });
            FieldInfo[] fields = obj.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
            foreach (FieldInfo field in fields)
            {
                try { field.SetValue(retval, DeepCopyByReflect(field.GetValue(obj))); }
                catch (Exception e)
                {
                    e.Message.ToString();
                }
            }
            return (T)retval;
        }

        //粘贴  方法的首字母大写？？？
        private void Paste_Click(object sender, EventArgs e)
        {
            if (copyLineHeaterStrip != null)
            {
                Point mouseLocation = PointToClient(MousePosition);
                int dx = mouseLocation.X - copyLineHeaterStrip.point1.X;
                int dy = mouseLocation.Y - copyLineHeaterStrip.point1.Y;
                //点击后 出现在鼠标点击的位置
                copyLineHeaterStrip.point1 = new Point(mouseLocation.X, mouseLocation.Y);
                copyLineHeaterStrip.point2 = new Point(copyLineHeaterStrip.point2.X + dx, copyLineHeaterStrip.point2.Y + dy);
                lineHeaterStripList.Add(copyLineHeaterStrip);//将线段对象加入集合中  
                copyLineHeaterStrip = null;
                Invalidate();
            }
            else if (copyCurvedHeaterStrip != null)
            {
                Point mouseLocation = PointToClient(MousePosition);
                int dx = mouseLocation.X - copyCurvedHeaterStrip.point1.X;
                int dy = mouseLocation.Y - copyCurvedHeaterStrip.point1.Y;
                //此处用数组保存会出现 当前线程正在被访问问题 有待解决
                copyCurvedHeaterStrip.point1 = new Point(mouseLocation.X, mouseLocation.Y);
                copyCurvedHeaterStrip.point2 = new Point(copyCurvedHeaterStrip.point2.X + dx, copyCurvedHeaterStrip.point2.Y + dy);
                copyCurvedHeaterStrip.point3 = new Point(copyCurvedHeaterStrip.point3.X + dx, copyCurvedHeaterStrip.point3.Y + dy);
                copyCurvedHeaterStrip.point4 = new Point(copyCurvedHeaterStrip.point4.X + dx, copyCurvedHeaterStrip.point4.Y + dy);
                copyCurvedHeaterStrip.addPoints();
                curvedHeaterStripList.Add(copyCurvedHeaterStrip);
                copyCurvedHeaterStrip = null;
                Invalidate();
            }
            isCopy = false;
        }

        private void EditValue_Click(object sender, EventArgs e)
        {
            if (changeLineIndex != -1)
            {
                //赋值 避免多个对象时 错乱
                changeLineNameIndex = changeLineIndex;
                lineHeaterStrip = lineHeaterStripList[changeLineIndex];
                box = new TextBox();
                box.Location = lineHeaterStrip.nameLocation;
                box.Size = new Size(40, 80);
                box.Text = (lineHeaterStrip.value).ToString();
                this.Controls.Add(box);
                box.Focus();//添加完控件之后 再设置焦点
            }
            if (changeTransformerIndex != -1)
            {
                changeTransformNameIndex = changeTransformerIndex;
                transformer = transformerList[changeTransformerIndex];
                //在方框内部双击 编辑文字
                transformerNameBox1 = new ComboBox();
                for (int i = 1; i <= 11; i++)
                {
                    transformerNameBox1.Items.Add("G" + i);
                }
                transformerNameBox1.Location = new Point(transformer.rect.X, transformer.rect.Y + 2);
                transformerNameBox1.Size = new Size(40, 10);
                this.Controls.Add(transformerNameBox1);

                transformerNameBox2 = new ComboBox();
                for (int i = 5; i <= 9; i++)
                {
                    transformerNameBox2.Items.Add(i + "A");
                    transformerNameBox2.Items.Add(i + "B");
                }
                transformerNameBox2.Location = new Point(transformer.rect.X + transformerNameBox1.Width, transformer.rect.Y + 2);
                transformerNameBox2.Size = new Size(40, 10);
                this.Controls.Add(transformerNameBox2);
            }
        }

        private void Delete_Click(object sender, EventArgs e)
        {
            if (changeRectIndex != -1)
            {
                heaterStripRectList.RemoveAt(changeRectIndex);
                changeRectIndex = -1;

            }
            else if (changeLineIndex != -1)
            {
                lineHeaterStripList.RemoveAt(changeLineIndex);
                changeLineIndex = -1;
            }
            else if (changeTransformerIndex != -1)
            {
                transformerList.RemoveAt(changeTransformerIndex);
                changeTransformerIndex = -1;
            }
            else if (changeCurvedIndex != -1)
            {
                curvedHeaterStripList.RemoveAt(changeCurvedIndex);
                changeCurvedIndex = -1;
            }
            //删除完 会出现鼠标图标异常情况 在删除之后整体做鼠标形态的初始化
            Cursor = Cursors.Default;
            Invalidate();
        }

        private void HeaterStripTransformer_Click(object sender, EventArgs e)
        {
            //插入变压器标志
            insertTransformerFlag = true;
        }

        private void ConfigHeaterStrip_Load(object sender, EventArgs e)
        {
            this.BackColor = Color.LightGray;
        }

        private void HeaterStripLine_Click(object sender, EventArgs e)
        {
            insertLineFlag = true;
        }

        private void CurvedHeaterStrip_Click(object sender, EventArgs e)
        {
            insertCurvedHeaterStripFlag = true;
        }

        private void HeaterStripRect_Click(object sender, EventArgs e)
        {
            insertRectFlag = true;
        }

        private void SaveFile_Click(object sender, EventArgs e)
        {
            //保存
            SaveFileDialog dlg = new SaveFileDialog
            {
                //设置一个打开的初始目录
                InitialDirectory = Directory.GetCurrentDirectory(),
                Filter = "json files (*.json)|*.json",
                FilterIndex = 1,
                RestoreDirectory = true
            };
            //将各个图元数据list数据添加进要序列化的数据list
            List<JObject> JObjList = new List<JObject>();
            JObject obj = JObject.Parse("{\"regionWidth\" : " + this.ClientRectangle.Width + ", \"regionHeight\" : " + this.ClientRectangle.Height + ", \"type\" : -1}");
            JObjList.Add(obj);
            AddObjToSerializeDataList<HeaterStripRect>(JObjList, heaterStripRectList);
            AddObjToSerializeDataList<HeaterStripTransformer>(JObjList, transformerList);
            AddObjToSerializeDataList<CurvedHeaterStrip>(JObjList, curvedHeaterStripList);
            AddObjToSerializeDataList<LineHeaterStrip>(JObjList, lineHeaterStripList);

            //调用序列化函数对数据list进行序列化
            string jsonStr = JsonConvert.SerializeObject(JObjList, Formatting.Indented, new JsonSerializerSettings
            {
                TypeNameHandling = TypeNameHandling.All
            });

            if (dlg.ShowDialog() == DialogResult.OK)
            {
                string FilePath = dlg.FileName;
                File.WriteAllText(FilePath, jsonStr);
            };

        }
        private void AddObjToSerializeDataList<T>(List<JObject> list, List<T> GraphList)
        {
            foreach (dynamic obj in GraphList)
            {
                JObject JObj = (JObject)JToken.FromObject(obj);
                list.Add(JObj);
            }
        }

        private void OpenFile_Click(object sender, EventArgs e)
        {
            //打开
            OpenFileDialog dlg = new OpenFileDialog
            {
                InitialDirectory = Directory.GetCurrentDirectory(),
                Filter = "json files (*.json)|*.json",
                FilterIndex = 1,
                RestoreDirectory = true
            };
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                string FilePath = dlg.FileName;
                string jsonStr = File.ReadAllText(FilePath);
                List<JObject> varList = new List<JObject>();
                //调用反序列化函数得到JObject对象list
                varList = JsonConvert.DeserializeObject<List<JObject>>(jsonStr);
                //遍历JObject对象list
                foreach (JObject varobj in varList)
                {
                    //使用JObject对象的键值获取方法得到数据对象类型
                    string str = varobj["type"].ToString();

                    //根据对象类型进行对象重构
                    if (int.Parse(str) == -1)
                    {
                        //画布尺寸
                        int regionWdith = int.Parse(varobj["regionWidth"].ToString());
                        int regionHeight = int.Parse(varobj["regionHeight"].ToString());
                        this.Size = new Size(regionWdith, regionHeight);
                        Invalidate();
                    }
                    switch (int.Parse(str))
                    {
                        case (int)GraphType.type_rect:
                            HeaterStripRect heaterStripRect = varobj.ToObject<HeaterStripRect>();
                            heaterStripRectList.Add(heaterStripRect);
                            break;
                        case (int)GraphType.type_transformer:
                            HeaterStripTransformer heaterStripTransformer = varobj.ToObject<HeaterStripTransformer>();
                            transformerList.Add(heaterStripTransformer);
                            break;
                        case (int)GraphType.type_line:
                            LineHeaterStrip lineHeaterStrip = varobj.ToObject<LineHeaterStrip>();
                            lineHeaterStripList.Add(lineHeaterStrip);
                            break;
                        case (int)GraphType.type_curved:
                            CurvedHeaterStrip curvedHeaterStrip = varobj.ToObject<CurvedHeaterStrip>();
                            curvedHeaterStripList.Add(curvedHeaterStrip);
                            break;
                    }
                }
            }
        }

        private void ConfigAddress_Click(object sender, EventArgs e)
        {
            ConfigAddress address = new ConfigAddress();
            if (changeCurvedIndex != -1)
            {
                curvedHeaterStrip = curvedHeaterStripList[changeCurvedIndex];
                address.dialNumber = curvedHeaterStrip.dialNumber;
                address.location = curvedHeaterStrip.location;
            }
            else if (changeLineIndex != -1)
            {
                lineHeaterStrip = lineHeaterStripList[changeLineIndex];
                address.dialNumber = lineHeaterStrip.dialNumber;
                address.location = lineHeaterStrip.location;
            }

            address.ShowDialog();//当前窗体关闭后再执行下面代码
            if (address.DialogResult == DialogResult.OK)
            {
                if (changeCurvedIndex != -1)
                {

                    curvedHeaterStrip.configAddressFlag = true;
                    curvedHeaterStrip.dialNumber = address.dialNumber;
                    curvedHeaterStrip.location = address.location;
                    curvedHeaterStrip.penColor = Color.FromArgb(28, 134, 238);
                    Invalidate();
                }
                else if (changeLineIndex != -1)
                {

                    lineHeaterStrip.configAddressFlag = true;
                    lineHeaterStrip.dialNumber = address.dialNumber;
                    lineHeaterStrip.location = address.location;
                    lineHeaterStrip.penColor = Color.FromArgb(28, 134, 238);
                    Invalidate();
                }
            }
        }
    }
}
